package de.stefanocke.roo.wicket.entity

import de.stefanocke.roo.wicket.Stereotypes
import de.stefanocke.roo.wicket.base.WicketItdBuilder
import static extension de.stefanocke.roo.wicket.base.WicketItdBuilder.*
import java.lang.reflect.Modifier

import static de.stefanocke.roo.xtend.Method.*

import static extension de.stefanocke.roo.xtend.MethodSignature.*

class EntityInterfacesItdBuilder extends WicketItdBuilder {
	override EntityInterfacesMetadata getMetadata(){
		super.metadata as EntityInterfacesMetadata
	} 
	override getInterfaces(){
		EntityInterfacesMetadata::INTERFACES
			.filter(s | s.stereotype != null)
			.map(s | s.stereotype(typeArgument(s)))
	}
	def typeArgument(String stereotype){
		switch stereotype{
			case Stereotypes::ENTITY_IDENTIFIABLE : metadata.identifierAccessor.returnType
			case Stereotypes::ENTITY_VERSIONED : metadata.versionAccessor.returnType
			default : null
		}
	}
	
	override getMethods(){
		methodsToImplement().map(toImplement |{ 
				val stereotype = stereotypeAnnotation(toImplement).value as String
				val methodToDelegateTo = methodToDelegateTo(stereotype)
				
				if(methodToDelegateTo != null &&
					methodToDelegateTo.methodName != toImplement.methodName
				) {
					method(
						signature(Modifier::PUBLIC, 
							methodToDelegateTo.returnType, 
							toImplement.methodName.symbolName, 
							methodToDelegateTo.parameters			
						),
						//TODO: Handle void return type
						[|'''
						return «methodToDelegateTo.methodName»(«FOR p : methodToDelegateTo.parameterNames SEPARATOR ", "»«p.symbolName»«ENDFOR»);
						''']
					)
				}
			})
			.filter(m | m != null) 
	}
	
	def methodsToImplement(){
		EntityInterfacesMetadata::INTERFACES
			.map(s | s.stereotypeDetails)
			.filter(sd | sd != null)
			.map(sd | sd.declaredMethods)
			.flatten
			.filter(m | m.stereotypeAnnotation != null)	
	}
	
	
	def methodToDelegateTo(String stereotype){
		switch stereotype{
			case Stereotypes::ENTITY_ID_ACCESSOR : metadata.identifierAccessor
			case Stereotypes::ENTITY_VERSION_ACCESSOR : metadata.versionAccessor
			default : null
		}
	}
	
	
	
}